#!/usr/bin/env ruby
#  jumbalaya_core.rb
#  Created by Paul Gower on 2007-10-24.
#  Copyright (c) 2007. All rights reserved.

module Jumbalaya

  class Core
    @@adaptor = nil
    @columns = []
    @id = nil

    def id
      @id
    end

    # i dont want new to create new records, i want create to do it, but new seems like it cant be stopped from passing something back

    def self.create(params={})
      t_id = @@adaptor.create_record(self.table_name,params)

      update_columns
    end

    private

    def initialize(params={})
      # passed an id that exists in the db, load the id and return the object
      # passed an id that does not exist in the db, return nil
      # passed no id, but a big bunch of 


      if params[:adaptor] then
        @@adaptor = params[:adaptor]
      else
        unless @@adaptor then @@adaptor = Jumbalaya::Database.new(params[:type] || :sqlite3) end
        end

        if params[:id] and @@adaptor.has_id?(params[:id], table_name) then
          @id = params[:id]
          update_columns
        elsif params[:id] and not @@adaptor.has_id?(params[:id], table_name) then
          raise "Given ID does not exist"
        elsif not params[:id] then
          @@adaptor.find(:first, table_name)
        end

        # if params[:id] then
        #   if @@adaptor.has_id?(params[:id], table_name) then
        #     @id = params[:id]
        #     update_columns
        #   end
        # else
        #   
        #   en
      end
    end

      def update_columns
        @columns = @@adaptor.get_columns(table_name)
      end

      def table_name
        self.class.to_s.downcase
      end

      def self.table_name
        self.name.to_s.downcase
      end

      def self.id_to_object(o_id)
        if o_id.is_a?(Integer) then
          self.new(:id => o_id)
        elsif o_id.is_a?(Array) then
          o_a = []
          o_id.each do |o|
            o_a << self.id_to_object(o)
          end
          o_a
        else
          return nil
        end
      end

      def method_missing(method_id,*params)
        puts "method_missing: #{method_id.to_s}, passed: #{params.to_s}"
        if @columns.include?(method_id.to_s) then
          @@adaptor.get_value(id,method_id.to_s,table_name)
        elsif regexmatch = /(.*)=$/.match(method_id.to_s) then
          unless regexmatch[1] == "id" then @@adaptor.set_value(id,regexmatch[1],params.first,table_name) end
          else
            raise NoMethodError, method_id.to_s
          end
        end
      end

      def self.method_missing(method_id,*params)
        # this is a class method, if no adaptor has been setup then we should at least try with the defaults before failing
        puts "self.method_missing: method_id: #{method_id.to_s}, params: #{params.inspect}"
        if not @@adaptor then self.new end
          if /^find$/.match(method_id.to_s)
            self.id_to_object(@@adaptor.find(params.first,self.table_name))
          elsif regexmatch = /find_by_(.*)/.match(method_id.to_s)
            self.id_to_object(@@adaptor.get_value_by(regexmatch[1],params.first,self.table_name))
          elsif regexmatch = /find_by_(.*)_and_(.*)/.match(method_id.to_s)
            self.id_to_object(@@adaptor.get_value_by_and(regexmatch[1],params.first,regexmatch[2],params[1], self.table_name))
          else 
            raise NoMethodError, method_id.to_s
          end
        end
      end


  end
  
  class Core < Jumbalaya::Database
    @@
    def initialize(params={})
      
    end
    
    def self.register_database(type, params={})
      
    end
    
  private
    def table_name
      self.class.to_s.downcase
    end
  
    def self.table_name
      self.name.to_s.downcase
    end
    
    def self.create_object_from_record(id)
      
    end
    
    def method_missing(method_id, *params)
      puts "method_missing: #{method_id.to_s}, passed: #{params.to_s}"
      if @columns.include?(method_id.to_s) then
        @@adaptor.get_value(id,method_id.to_s,table_name)
      elsif regexmatch = /(.*)=$/.match(method_id.to_s) then
        unless regexmatch[1] == "id" then @@adaptor.set_value(id,regexmatch[1],params.first,table_name) end
        else
          raise NoMethodError, method_id.to_s
        end
      end
    end
    
    def self.method_missing(method_id, *params)
      puts "self.method_missing: method_id: #{method_id.to_s}, params: #{params.inspect}"
      if not @@adaptor then self.new end
        if /^find$/.match(method_id.to_s)
          self.id_to_object(@@adaptor.find(params.first,self.table_name))
        elsif regexmatch = /find_by_(.*)/.match(method_id.to_s)
          self.id_to_object(@@adaptor.get_value_by(regexmatch[1],params.first,self.table_name))
        elsif regexmatch = /find_by_(.*)_and_(.*)/.match(method_id.to_s)
          self.id_to_object(@@adaptor.get_value_by_and(regexmatch[1],params.first,regexmatch[2],params[1], self.table_name))
        else 
          raise NoMethodError, method_id.to_s
        end
      end
    end
    
    
    
end